﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TireService.Data;
using DevExpress.Web.ASPxCallback;
using DevExpress.Web.ASPxGridView;
using DevExpress.Web.ASPxEditors;
using System.Web.Security;

namespace TireService.Web.UserControls
{
    public partial class ucEditTask : System.Web.UI.UserControl
    {
        private string _controlname = "EditTask";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Convert.ToBoolean(Session["UserControlLoaded" + _controlname]))
            {
                // Initiate datalayer
                TireServiceDB db = new TireServiceDB();

                // Show task
                LoadTask(Convert.ToInt32(Session["TaskId" + _controlname]), db);
            }
        }

        protected void callbackEditTaskPanel_Callback(object source, DevExpress.Web.ASPxClasses.CallbackEventArgsBase e)
        {
            Session["TaskId" + _controlname] = Convert.ToInt32(e.Parameter);

            LoadUserControl(Convert.ToInt32(e.Parameter));
        }

        /// <summary>
        /// Public function for loading usercontrol
        /// </summary>
        public void LoadUserControl(int TaskId)
        {
            // Show usercontrol edit form
            pEditTask.Visible = true;

            // Initiate datalayer
            TireServiceDB db = new TireServiceDB();

            // Load form data
            LoadUserControlData(db);


            if (TaskId != 0)
            {
                LoadTask(TaskId, db);
            }
            else
            {
                // Error
                throw new ArgumentException("Opgave ikke fundet");
            }
        }

        /// <summary>
        /// Function that load form data for edit
        /// </summary>
        /// <param name="db">Connection to database</param>
        private void LoadUserControlData(TireServiceDB db)
        {
            // TODO: If needed
        }

        /// <summary>
        /// Function that load task and set edit form values
        /// </summary>
        /// <param name="TaskId">Id on task to load</param>
        /// <param name="db">Connection to database</param>
        private void LoadTask(int TaskId, TireServiceDB db)
        {
            // Fetch task
            Task task = db.GetTask(TaskId);

            // Set values in edit form
            if (task != null)
            {
                lblTaskIdValue.Text = task.TaskId.ToString();
                lblCreateDateValue.Text = task.Createdate.ToShortDateString();
                hlCustomerId.Text = task.CustomerId.ToString();
                hlCustomerId.NavigateUrl = string.Format("~/View/CustomerView/EditCustomerData.aspx?CustomerId={0}", task.CustomerId);
                lblRegistrationNumberValue.Text = db.GetCarRegistrationNumber(Convert.ToInt32(task.CarId));
                
                CarTireSetView tireset = db.CarTireSetViews.SingleOrDefault(p => p.TireSetId == Convert.ToInt32(task.TireSetId));

                lblTireSetInfoValue.Text = tireset.TireTypeDescription + " (" + tireset.TireSetStatusDescription + ")";

                lblTaskTypeIdValue.Text = db.GetTaskTypeDescription(task.TaskTypeId);
                lblTaskTypeStatusIdValue.Text = db.GetTaskTypeStatusDescription(task.TaskTypeStatusId);

                // TODO: Write code for below
                //lblCurrentDependentOnTaskValue.Text = 
                lblCurrentDependentOfTaskValue.Text = task.DependentTaskId.ToString();

                // Only show tasks that do not already have childdependecy created
                ddlDependentOnTask.DataSource = db.GetDependentChildTasks(Convert.ToInt32(task.CustomerId), Convert.ToInt32(task.CarId), Convert.ToInt32(task.TireSetId), false);
                ddlDependentOnTask.ValueField = "TaskId";
                ddlDependentOnTask.DataBind();

                // Only show tasks that do not already have dependecy created
                ddlDependentOfTask.DataSource = db.GetTasksWithDependency(Convert.ToInt32(task.CustomerId), Convert.ToInt32(task.CarId), Convert.ToInt32(task.TireSetId), false);
                ddlDependentOfTask.ValueField = "TaskId";
                ddlDependentOfTask.DataBind();

                // Validate if servicetaskdrive panel should be shown
                pServiceTaskDrive.Visible = (task.TaskTypeId == (int)Shared.TaskType.ServiceDrive);

                if (pServiceTaskDrive.Visible)
                {
                    // Show values in form for adresses
                    txtPrimaryAddress.Text = task.PrimaryAddress;
                    txtPrimaryZipCode.Text = task.PrimaryZipCode;
                    txtPrimaryCity.Text = task.PrimaryCity;
                    txtRemarkToAddress.Text = task.CommentToAddress;
                    txtSecondaryAddress.Text = task.SecondaryAddress;
                    txtSecondaryZipCode.Text = task.SecondaryZipCode;
                    txtSecondaryCity.Text = task.SecondaryCity;
                    txtRemarkToSecondaryAddress.Text = task.CommentToSecondaryAddress;
                }

                BindTaskDetails(task.TaskId, db);
                
                // Prepare data for editmode of taskdetail
                GridViewDataComboBoxColumn ddlTaskDetailType = gvTaskDetail.Columns["TaskDetailTypeDropdown"] as GridViewDataComboBoxColumn;
                ddlTaskDetailType.PropertiesComboBox.ValueType = typeof(int);
                ddlTaskDetailType.PropertiesComboBox.DataSource = db.GetTaskDetailTypes();
                ddlTaskDetailType.PropertiesComboBox.TextField = "Description";
                ddlTaskDetailType.PropertiesComboBox.ValueField = "TaskDetailTypeId";
                ddlTaskDetailType.PropertiesComboBox.DropDownStyle = DropDownStyle.DropDownList;
                ddlTaskDetailType.PropertiesComboBox.IncrementalFilteringMode = IncrementalFilteringMode.StartsWith;
            }
            else
            {
                // Error
                throw new ArgumentException("Opgave kunne ikke loades");
            }

            Session["UserControlLoaded" + _controlname] = true;
        }

        private void BindTaskDetails(int TaskId, TireServiceDB db)
        {
            gvTaskDetail.DataSource = db.GetTaskDetails(TaskId);
            gvTaskDetail.DataBind();
        }

        protected void SetNullItem(object control)
        {
            ASPxComboBox cb = (ASPxComboBox)control;
            if (cb != null)
            {
                ListEditItem item = new ListEditItem("(ingen)", "");
                cb.Items.Insert(0, item);
                cb.SelectedItem = item;
            }
        }

        protected void ddlDependentOnTask_DataBound(object sender, EventArgs e)
        {
            SetNullItem(sender);
        }

        protected void ddlDependentOfTask_DataBound(object sender, EventArgs e)
        {
            SetNullItem(sender);
        }

        /// <summary>
        /// Callback function that saves task
        /// </summary>
        protected void callBackSaveTask_Callback(object sender, CallbackEventArgs e)
        {
            try
            {
                //// Get values from client
                //string[] param = e.Parameter.Split('|');

                //int TireSetId = Convert.ToInt32(param[18]);

                //// Initiate datalayer
                //TireServiceDB db = new TireServiceDB();

                //TireSet tireset = new TireSet();

                //if (TireSetId != 0)
                //{
                //    // Load tireset
                //    tireset = db.GetTireSet(TireSetId);
                //}
                //tireset.TireTypeId = Convert.ToInt32(param[0]);
                //tireset.RimType = Convert.ToInt32(param[1]);
                //tireset.Size = Convert.ToDecimal(param[2]);
                //tireset.Width = Convert.ToDecimal(param[3]);
                //tireset.Height = Convert.ToDecimal(param[4]);
                //if (param[5] != "0") tireset.TireSpeedIndexId = Convert.ToInt32(param[5]);
                //if (param[6] != "0") tireset.TireLoadIndexId = Convert.ToInt32(param[6]);
                //if (param[7] != "0") tireset.TireBrandId = Convert.ToInt32(param[7]);
                //if (param[8] != "") tireset.TireBrandNote = Convert.ToString(param[8]);
                //tireset.LockingBolt = Convert.ToBoolean(param[9]);
                //tireset.HubCaps = Convert.ToBoolean(param[10]);
                //tireset.RunFlatTire = Convert.ToBoolean(param[11]);
                //tireset.NeedBalancing = Convert.ToBoolean(param[12]);
                //tireset.ExtraBolts = Convert.ToBoolean(param[13]);
                //tireset.RimProtection = Convert.ToBoolean(param[14]);
                //if (param[15] != "") tireset.LastBalancingDate = Convert.ToDateTime(param[15]);
                //if (param[16] != "") tireset.ManufactureDate = Convert.ToDateTime(param[16]);
                //if (param[17] != "0") tireset.SocketWrenchSize = Convert.ToInt32(param[17]);
                //tireset.DummyTireSet = false;
                ////tireset.TireSetStatusId = 

                //if (TireSetId == 0)
                //{
                //    db.AddTireSet(tireset);
                //}

                //// Commit changes to database
                //db.SubmitChanges();

                //// Dispose database connection
                //db.Dispose();
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException("Fejl opstod: " + ex.Message);
            }
        }

        /// <summary>
        /// Callback function that cancel task
        /// </summary>
        protected void callBackCancelTask_Callback(object sender, CallbackEventArgs e)
        {
            try
            {
                // Initiate datalayer
                TireServiceDB db = new TireServiceDB();

                TaskBLL taskBLL = new TaskBLL();

                // Get taskid
                int TaskId = Convert.ToInt32(e.Parameter);

                // Get user
                Guid userid = new Guid(Membership.GetUser().ProviderUserKey.ToString());

                // Cancel task
                taskBLL.CancelTask(db, TaskId, userid, false);

                // Dispose database connection
                db.Dispose();
            }
            catch (Exception ex)
            {
                // Error
                throw new ArgumentException(ex.Message);
            }
        }

        /// <summary>
        /// Postback function that updates gridview with tasks
        /// </summary>
        protected void gvTaskDetail_CustomCallback(object sender, DevExpress.Web.ASPxGridView.ASPxGridViewCustomCallbackEventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            // Show taskdetails
            BindTaskDetails(Convert.ToInt32(Session["TaskId" + _controlname]), db);
        }

        /// <summary>
        /// Gridview function for updating task
        /// </summary>
        protected void gvTaskDetail_RowUpdating(object sender, DevExpress.Web.Data.ASPxDataUpdatingEventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            // Get id
            int TaskDetailId = Convert.ToInt32(e.Keys["TaskDetailId"]);

            TaskBLL taskBLL = new TaskBLL();

            TaskDetail taskdetail = db.GetTaskDetail(TaskDetailId);
            Task task = db.GetTask(taskdetail.TaskId);

            Guid userid = new Guid(Membership.GetUser().ProviderUserKey.ToString());

            taskBLL.CreateTaskLog(db, task, DateTime.Now, task.TaskTypeStatusId, task.TaskTypeStatusId, userid, "Redigering af delopgave Id: " + taskdetail.TaskDetailId.ToString());

            taskdetail.TaskDetailTypeId = Convert.ToInt32(e.NewValues["TaskDetailTypeId"]);
            taskdetail.Amount = Convert.ToDecimal(e.NewValues["Amount"]);
            taskdetail.NoteToEmployee = e.NewValues["NoteToEmployee"].ToString();
            taskdetail.NoteFromEmployee = e.NewValues["NoteFromEmployee"].ToString();

            // Commit changes to database
            db.SubmitChanges();

            // End edit mode
            e.Cancel = true;
            gvTaskDetail.CancelEdit();

            BindTaskDetails(taskdetail.TaskId, db);

            // Close db connection
            db.Dispose();
        }

        /// <summary>
        /// Gridview function for creating customer car
        /// </summary>
        protected void gvTaskDetail_RowInserting(object sender, DevExpress.Web.Data.ASPxDataInsertingEventArgs e)
        {
            TireServiceDB db = new TireServiceDB();

            // Get id
            int TaskId = Convert.ToInt32(e.NewValues["TaskId"]);

            TaskBLL taskBLL = new TaskBLL();

            TaskDetail taskdetail = new TaskDetail();
            Task task = db.GetTask(TaskId);

            Guid userid = new Guid(Membership.GetUser().ProviderUserKey.ToString());

            taskBLL.AddTaskDetailToExistingTask(db, task, taskdetail, Convert.ToInt32(e.NewValues["TaskDetailTypeId"]), Convert.ToDecimal(e.NewValues["Amount"]), e.NewValues["NoteToEmployee"].ToString(), userid, true);

            // Commit changes to database
            db.SubmitChanges();

            // End edit mode
            e.Cancel = true;
            gvTaskDetail.CancelEdit();

            BindTaskDetails(taskdetail.TaskId, db);

            // Close db connection
            db.Dispose();
        }

        protected void gvTaskDetail_CustomButtonCallback(object sender, ASPxGridViewCustomButtonCallbackEventArgs e)
        {
            if (e.ButtonID == "MarkCompleted") 
            {
                TireServiceDB db = new TireServiceDB();

                int TaskDetailId = (int)gvTaskDetail.GetRowValues(e.VisibleIndex, "TaskDetailId");

                TaskDetail taskdetail = db.GetTaskDetail(TaskDetailId);
                TaskBLL taskBLL = new TaskBLL();
                
                Guid userid = new Guid(Membership.GetUser().ProviderUserKey.ToString());

                // Check if taskdetail is already marked as completed
                if (taskdetail.Completed)
                {
                    // Get number for taskdetails and number of active taskdetails (not completed or cancelled)
                    int taskdetailcount = db.CountTaskDetails(taskdetail.TaskId);
                    int activetaskdetailcount = db.CountOpenTaskDetails(taskdetail.TaskId);

                    Task task = db.GetTask(taskdetail.TaskId);

                    // Check if any open taskdetails
                    if (activetaskdetailcount == 0)
                    {
                        // No open tasks - un-setting taskdetail to completed (== false) reopens Task

                        // TODO: Make code
                    }
                    else
                    {
                        taskdetail.Completed = false;
                        taskBLL.CreateTaskLog(db, task, DateTime.Now, task.TaskTypeStatusId, task.TaskTypeStatusId, userid, "Delopgave genåbnet Id: " + taskdetail.TaskDetailId.ToString());
                    }
                }
                else
	            {
                    // Get number for taskdetails and number of active taskdetails (not completed or cancelled)
                    int taskdetailcount = db.CountTaskDetails(taskdetail.TaskId);
                    int activetaskdetailcount = db.CountOpenTaskDetails(taskdetail.TaskId);

                    // Check if any open taskdetails
                    if (taskdetailcount == activetaskdetailcount)
                    {
                        // No open tasks - setting taskdetail to completed = false reopens Task
                        // TODO: Make code
                    }
                    else
                    {
                        // Check if last taskdetail is being marked as completed
                        if ((taskdetailcount - 1) == activetaskdetailcount)
                        {
                            // Last task being closed - change task status
                        }
                        else
                        {

                        }
                    }


                    // Taskdetail set as cancelled can not be set as completed
                    if (taskdetail.Cancelled)
                    {
                        return;
                    }

                    taskdetail.Completed = true;
                    //CountTaskDetailsCompleted
	            }

            }
            if (e.ButtonID == "MarkCancelled")
            {
                int TaskDetailId = (int)gvTaskDetail.GetRowValues(e.VisibleIndex, "TaskDetailId");
            }

        }
    }
}